import random
from datetime import datetime, timedelta

from flask import current_app, g
from flask_restful import Resource
from flask_restful.inputs import regex
from flask_restful.reqparse import RequestParser
from sqlalchemy.orm import load_only

from app import redis_cluster, db
from utils.constants import SMS_CODE_EXPIRE
from utils.verification import SendSms

from models.user import User

# from common.models.user import User
from common.utils.jwt_util import generate_jwt


class SMSCodeResource(Resource):
    """获取短信验证码"""

    def get(self, mobile):


        #TODO 判断是否频繁发送

        # 生成短信验证码
        rand_num = '%06d' % random.randint(0, 999999)

        # 发送短信  第三方短信平台 celery
        print('短信验证码: "mobile": {}, "code": {}'.format(mobile, rand_num))
        if not SendSms().send_message(mobile=mobile, datas=(rand_num, '3')):
            return {
                'message': "请重新发送",
                'code': 400,
                'mobile': mobile
            }

        # 保存验证码(redis)  app:code:18912341234   123456
        key = 'app:code:{}'.format(mobile)
        redis_cluster.set(key, rand_num, ex=SMS_CODE_EXPIRE)

        # 返回结果
        return {'mobile': mobile}


from utils.parser import mobile as mobile_type


class LoginResource(Resource):
    """注册登录"""

    def post(self):
        # 获取参数
        parser = RequestParser()
        parser.add_argument('mobile', required=True, location='json', type=mobile_type)
        parser.add_argument('code', required=True, location='json', type=regex(r'^\d{6}$'))
        args = parser.parse_args()
        mobile = args.mobile
        code = args.code

        # 校验短信验证码
        key = 'app:code:{}'.format(mobile)
        real_code = redis_cluster.get(key)

        if not real_code or real_code != code:
            return {'message': 'Invalid Code', 'data': None}, 400

        # 删除验证码
        redis_cluster.delete(key)

        # 校验成功, 查询数据库
        user = User.query.options(load_only(User.id)).filter(User.mobile == mobile).first()

        if user:  # 如果有, 取出用户id, 更新最后登录时间
            user.last_login = datetime.now()

        else:  # 如果没有, 创建新用户
            user = User(mobile=mobile, name=mobile, last_login=datetime.now())
            db.session.add(user)

        db.session.commit()

        # 生成jwt
        # token = generate_jwt({'userid': user.id}, expiry=datetime.utcnow() + timedelta(days=current_app.config['JWT_EXPIRE_HOURS']))

        token, refresh_token = self._returnToken(user.id)
        # 返回结果
        return {'token': token,
                'refresh_token': refresh_token}, 201

    def _returnToken(self, user_id, isr=True):
        # 生成jwt
        refresh_token = generate_jwt({'userid': user_id,
                                      'is_refresh': True},
                                     expiry=datetime.utcnow() + timedelta(days=current_app.config['JWT_EXPIRE_DAYS']))
        if isr:
            token = generate_jwt({'userid': user_id},
                                 expiry=datetime.utcnow() + timedelta(days=current_app.config['JWT_EXPIRE_HOURS']))

            return token, refresh_token

        else:
            return refresh_token

    def put(self):
        if g.is_refresh:

            refresh_token = self._returnToken(g.userid, False)

            return {'refresh_token': refresh_token}, 201
        else:
            return {'message': 'Invalid Token', 'data': None}, 401
